#include "ChatServer.h"
#include <QThread>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
ChatServer::ChatServer(QObject *parent)
    : QObject(parent), m_sslServer(new QSslServer(this)) {
    // 监听指定端口
    if (!m_sslServer->listen(QHostAddress::Any, 1234)) {
        qCritical() << "Failed to listen on port 1234:" << m_sslServer->errorString();
        return;
    }

    qDebug() << "SSL server is listening on port 1234...";

    // 连接信号和槽
    connect(m_sslServer, &QSslServer::newSslConnection, this, &ChatServer::handleNewSslConnection);
}

void ChatServer::handleNewSslConnection(QSslSocket *sslSocket) {
    qDebug() << "New SSL connection, socket descriptor:" << sslSocket->socketDescriptor();
    QVariant clientTagValue = sslSocket->property("clientTag");
    QString clientTag;

    // 获取当前的本地时间
    QDateTime currentTime = QDateTime::currentDateTime();
    // 格式化时间，使用 [yyyy/MM/dd hh:mm:ss] 格式
    QString formattedTime = "[" + currentTime.toString("yyyy/MM/dd hh:mm:ss") + "]";
    QString message = formattedTime+" Hello,welcome to this! Dear "+clientTag+". \n";
    sslSocket->write(message.toUtf8());
    clients.append(sslSocket);
    // 连接信号和槽
    connect(sslSocket, &QSslSocket::readyRead, this, &ChatServer::handleSslSocketReadyRead);
    connect(sslSocket, &QSslSocket::disconnected, this, &ChatServer::handleSslSocketDisconnected);
}

void ChatServer::private_post(QString recipient, QString messageContent){
    foreach (QSslSocket *Client, clients) {
        QString clientTag;
        // 获取 clientTag 属性的值
        QVariant clientTagValue = Client->property("clientTag");

        // 将 QVariant 转换为实际的类型（例如 QString）
        if (clientTagValue.isValid()) {
            clientTag = clientTagValue.toString();
        }
        if (clientTag == recipient){
            Client->write(messageContent.toUtf8());
            Client->write("\n");
            Client->flush();
        }
    }
}

void ChatServer::public_post(QString message){
    foreach (QSslSocket *Client, clients) {
        if (!Client->isOpen()) {
            QVariant clientTagValue = Client->property("clientTag");
            QString clientTag;
            // 将 QVariant 转换为实际的类型（例如 QString）
            if (clientTagValue.isValid()) {
                clientTag = clientTagValue.toString();
            }
            qDebug() << clientTag+ "客户已关闭，无法写入数据";
            continue;
        }
        Client->write(message.toUtf8());
        Client->write("\n");
        Client->flush();
    }
}


void ChatServer::handleSslSocketReadyRead() {

    QSslSocket *client = qobject_cast<QSslSocket *>(sender());
    if (!client){
        qDebug()<<"错误发生，未检测到socket";
        delete client;
    }
    while (client->canReadLine()) {
        QString message = QString::fromUtf8(client->readLine()).trimmed();
        qDebug()<<message;
        QString onlineMessage;
        if(message == "command -query"){
            onlineMessage = "command -query:";
            foreach (QSslSocket *s, clients) {
                QVariant clientTagValue = s->property("clientTag");
                QString clientTag;
                // 将 QVariant 转换为实际的类型（例如 QString）
                if (clientTagValue.isValid()) {
                    clientTag = clientTagValue.toString();
                    onlineMessage = onlineMessage + " " + clientTag;
                }
            }

            client->write(onlineMessage.toUtf8());
            client->write("\n");
            continue;
        }

        // 定义正则表达式S
        QRegularExpression regex(R"(To\s+(\w+):\s*(.*))");
        QRegularExpressionMatch match = regex.match(message);

        if (match.hasMatch()) {
            QString recipient = match.captured(1).trimmed(); // 提取收件人
            QString messageContent = match.captured(2).trimmed(); // 提取消息内容

            private_post(recipient, messageContent);
        }else{
            public_post(message);

        }
    }
}

void ChatServer::handleSslSocketDisconnected() {
    QSslSocket *sslSocket = qobject_cast<QSslSocket *>(sender());
    if (sslSocket) {
        qDebug() << "Client disconnected:" << sslSocket->socketDescriptor();
        clients.removeOne(sslSocket);
        delete sslSocket;
    }
}
